<template>
  <div class="jcamera">
    <div>
      <!-- 捕获人脸 -->
      <video
        id="video"
        ref="video"
        :width="width"
        :height="height"
        autoplay
        muted
      >
        您的浏览器不支持 video 标签。
      </video>

      <canvas id="canvas" ref="canvas" :width="width" :height="height" />
    </div>

    <p :style="'padding-top:' + (height + 20) + 'px'">
      {{ trackingText }}
    </p>
  </div>
</template>
<script>
import './tracking-min.js'
import './face-min.js'

let tracking = window.tracking

export default {
  name: 'Camera',
  emits: ['update:modelValue', 'capture'],
  props: {
    modelValue: {
      type: String,
    },
    width: {
      type: Number,
      default: () => {
        return 640
      },
    },
    height: {
      type: Number,
      default: () => {
        return 480
      },
    },
    frequence: {
      type: Number,
      default: () => {
        return 1
      },
    },
  },
  data() {
    return {
      tracker: null,
      trackerTask: null,
      trackingText: '正在启动用户谋体...',
      lastCaptureTime: null,
      context: null,
    }
  },
  computed: {
    video() {
      return this.$refs.video
    },
    canvas() {
      return this.$refs.canvas
    },
  },
  beforeUnmount() {
    this.stop()
  },
  methods: {
    tracking() {
      this.context = this.canvas.getContext('2d')
      this.tracker = new tracking.ObjectTracker(['face']) // tracker实例
      this.tracker.setInitialScale(4)
      this.tracker.setStepSize(2)
      this.tracker.setEdgesDensity(0.1)

      this.tracker.on('track', (e) => {
        this.context.clearRect(0, 0, this.canvas.width, this.canvas.height)
        if (e.data.length == 0) {
          return
        }

        let now = new Date().getTime()
        if (
          !this.lastCaptureTime ||
          now > this.lastCaptureTime + this.frequence * 1000
        ) {
          this.capture()
        }

        e.data.forEach((rect) => {
          this.context.strokeStyle = '#a64ceb'
          this.context.strokeRect(rect.x, rect.y, rect.width, rect.height)
          this.context.font = '11px Helvetica'
          this.context.fillStyle = '#fff'
          this.context.fillText(
            'x: ' + rect.x + 'px',
            rect.x + rect.width + 5,
            rect.y + 11
          )
          this.context.fillText(
            'y: ' + rect.y + 'px',
            rect.x + rect.width + 5,
            rect.y + 22
          )
        })
      })

      try {
        this.trackerTask = tracking.track('#video', this.tracker, {
          camera: true,
        }) // 开始追踪

        this.trackingText = '请调整摄像头至合适位置，将正脸置于框内'
      } catch (e) {
        console.error(e)
        this.trackingText = '访问用户媒体失败'
      }
    },
    stop() {
      if (this.trackerTask) {
        this.trackerTask.stop()
        this.trackerTask = null
      }

      if (this.video && this.video.srcObject) {
        this.video.srcObject.getTracks()[0].stop()
        this.video.srcObject = null
      }
    },
    capture() {
      this.context.clearRect(0, 0, this.canvas.width, this.canvas.height)

      this.context.drawImage(this.video, 0, 0, this.width, this.height)
      // 保存为base64格式
      let value = this.canvas.toDataURL('image/png', 0.3)

      this.$emit('update:modelValue', value)
      this.lastCaptureTime = new Date().getTime()

      this.$emit('capture', value)
    },
  },
}
</script>
<style lang="scss" scoped>
.jcamera {
  text-align: center;

  video,
  canvas {
    left: 20px;
    position: absolute;
  }
}
</style>
